import useUserStore from '@/store/user';
import { getuuid } from '@/utils';
import fingerprintjs from '@fingerprintjs/fingerprintjs';
import { useEffect, useRef } from 'react';
import io from 'socket.io-client';

let socket: SocketIOClient.Socket;
enum SocketEvent {
  newNotice = 'newNotice'
}
// const socketReconnectStatus = false;
// 全局的socket事件回调存储
const eventMaps = new Map<string, Map<string, (...args: unknown[]) => void>>();
// 初始化创建socket方法
let initPromise: Promise<unknown> | null = null;
/**
 * socket 实例初始化
 */
async function init() {
  try {
    const fpPromise = await fingerprintjs.load();
    const fp = await fpPromise;
    const result = await fp.get();
    const state = useUserStore.getState();
    socket = io('', {
      path: '/socket.io/',
      query: {
        type: 'web',
        id: result.visitorId,
        name: state.userinfo.username
      },
      transports: ['websocket'],
      timeout: 50000,
      reconnection: true,
      reconnectionDelay: 1000,
      reconnectionDelayMax: 5000,
      reconnectionAttempts: Infinity
    });
    socket.on('reconnect', () => {
      console.log('reconnect');
      // socketReconnectStatus = true;
    });
    socket.on('connect', () => {
      console.log('connect');
    });
  } catch (error) {
    // eslint-disable-next-line no-console
    console.log(error);
  }
}
/**
 * 异步获取socket实例，若实例未创建，会自动初始化并返回
 * @returns socket实例
 */
async function getSocket() {
  if (!socket) {
    if (!initPromise) {
      initPromise = new Promise((reslove) => {
        (async () => {
          await init();
          reslove(true);
        })();
      });
    }
    await initPromise;
  }
  return socket;
}

/**
 * hook 获取socket实例
 * @returns socket 实例
 */
export function useSocket() {
  const client = useRef<SocketIOClient.Socket>();
  if (client.current === undefined) {
    (async () => {
      client.current = await getSocket();
    })();
  }
  return client.current;
}
/**
 * 初始化绑定socket事件
 * @param eventName 事件名称
 */
async function initSocketEvent(eventName: SocketEvent) {
  const client = await getSocket();
  client.on(eventName, (...args: unknown[]) => {
    const map = eventMaps.get(eventName);
    map?.forEach((cb) => {
      cb(...args);
    });
  });
}
/**
 * 监听socket事件的自定义hook
 * @param eventName 事件名称
 * @param fn 事件回调
 */
export function useSocketOnEvent(eventName: SocketEvent, fn: (...args: any) => void) {
  // 持久化fn
  const fnRef = useRef(fn);
  fnRef.current = fn;
  useEffect(() => {
    const uuid = getuuid();
    let event = eventMaps.get(eventName);
    if (!event) {
      event = new Map();
    }
    event.set(uuid, fnRef.current);
    eventMaps.set(eventName, event);
    if (event.size === 1) {
      initSocketEvent(eventName);
    }
    // connect事件监听
    // let connectEvent = eventMaps.get('connect');
    // if (!connectEvent) {
    //   connectEvent = new Map();
    // }
    // connectEvent.set(uuid, () => {
    //   // 如果是重连socket，自动注册事件
    //   if (socketReconnectStatus) {
    //     console.log('re');
    //     setSocketEvent(eventName);
    //   }
    // });
    // setSocketEvent('connect' as any);
    return () => {
      eventMaps.get(eventName)?.delete(uuid);
      // eventMaps.get('connect')?.delete(uuid);
    };
  }, [eventName]);
}
